package com.movie.db.util;

import java.io.File;
import java.io.FileWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;

import com.movie.comm.utils.StringUtil;
import com.sun.istack.internal.NotNull;

import java.io.BufferedWriter;
import java.sql.ResultSet;
import java.util.HashMap;
import java.util.Map;

/**
 * 
 * @ClassName: GenerateEntityMysql
 * @Description: 通过Mysql  生成Java 实体类
 * @author 左岩
 * @date 2018年12月6日 上午8:37:12
 *
 */
public class GenerateEntityMysql {
	private String url;// 数据库链接地址
	private String username;// 用户名
	private String password;// 密码
	private String tablename;// 表名
	private String databasename;// 数据库名
	private String packagename;// 欲生成的实体类的包名
	private String entityname;// 欲生成的实体类的名称
	private String path;// 生成的实体类的文件夹路径

	private Map<String, String> map = new HashMap<>();

	public GenerateEntityMysql(@NotNull String url, //
			@NotNull String username, //
			@NotNull String password, //
			@NotNull String tablename, //
			@NotNull String databasename, //
			@NotNull String packagename, //
			@NotNull String entityname, //
			@NotNull String path) {
		this.url = url;
		this.username = username;
		this.password = password;
		this.tablename = tablename;
		this.databasename = databasename;
		this.packagename = packagename;
		this.entityname = entityname;
		this.path = path;
	}

	public void generate() {
		// 查询欲生成实体类的表的详细信息
		String sql = "SELECT information_schema.`COLUMNS`.* FROM information_schema.`COLUMNS` WHERE information_schema.`COLUMNS`.TABLE_SCHEMA=? AND information_schema.`COLUMNS`.TABLE_NAME=?";
		try {
			Connection conn;
			PreparedStatement ps = null;
			Class.forName("com.mysql.jdbc.Driver");
			conn = DriverManager.getConnection(url, username, password);
			System.out.println("connect database success...");
			ps = conn.prepareStatement(sql);
			ps.setString(1, databasename);
			ps.setString(2, tablename);
			ResultSet rs = ps.executeQuery();
			StringBuilder sb = new StringBuilder();
			sb.append("package ");
			sb.append(packagename);
			sb.append(";\n");
			sb.append("public class ");
			sb.append(entityname);
			sb.append("{\n");
			// 生成成员变量
			while (rs.next()) {
				String column_name = rs.getString("COLUMN_NAME");
				column_name = StringUtil.underline2Camel(column_name.toLowerCase(), true);
				String data_type = rs.getString("DATA_TYPE");
				String column_comment = rs.getString("COLUMN_COMMENT");
				sb.append("\tprivate ");
				if (data_type.equalsIgnoreCase("TINYINT")) {
					sb.append("Boolean ");
					map.put(column_name, "Boolean");
				} else if (data_type.equalsIgnoreCase("SMALLINT") || data_type.equalsIgnoreCase("MEDIUMINT")
						|| data_type.equalsIgnoreCase("INT") || data_type.equalsIgnoreCase("INTEGER")) {
					sb.append("Integer ");
					map.put(column_name, "Integer");
				} else if (data_type.equalsIgnoreCase("BIGINT")) {
					sb.append("Long ");
					map.put(column_name, "Long");
				} else if (data_type.equalsIgnoreCase("FLOAT") || data_type.equalsIgnoreCase("DOUBLE")) {
					sb.append("Double ");
					map.put(column_name, "Double");
				} else if (data_type.equalsIgnoreCase("DECIMAL")) {
					sb.append("Decimal ");
					map.put(column_name, "Decimal");
				} else if (data_type.equalsIgnoreCase("DATE") || data_type.equalsIgnoreCase("TIME")
						|| data_type.equalsIgnoreCase("YEAR") || data_type.equalsIgnoreCase("DATETIME")
						|| data_type.equalsIgnoreCase("TIMESTAMP")) {
					sb.append("Date ");
					map.put(column_name, "Date");
				} else {
					sb.append("String ");
					map.put(column_name, "String");
				}
				sb.append(column_name).append("; // ").append(column_comment).append("\n");
			}
			sb.append("\n");
			// 生成get|set方法
			processAllMethod(sb);
			sb.append("}");
			// FileOutputStream fos = new FileOutputStream();
			// 打印文件
			File file = new File(
					("/".equals(path.substring(path.length() - 1)) ? path : (path + "/")) + entityname + ".java");
			if (!file.exists()) {
				file.createNewFile();
			} else {
				file.delete();
				file.createNewFile();
			}
			BufferedWriter bw = new BufferedWriter(new FileWriter(file));
			bw.write(sb.toString());
			bw.flush();
			bw.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 生成get,set
	 *
	 * @param sb
	 */
	private void processAllMethod(StringBuilder sb) {
		// 遍历map,此为java8遍历
		map.forEach((k, v) -> {
			// 键值首字母大写
			String m = k.substring(0, 1).toUpperCase() + k.substring(1);
			// 生成set
			sb//
					.append("\tpublic void set")//
					.append(m)//
					.append("(")//
					.append(v)//
					.append(" ")//
					.append(k)//
					.append("){\n")//
					.append("\t\tthis.")//
					.append(k)//
					.append(" = ")//
					.append(k)//
					.append(";\n")//
					.append("\t}\n\n");//
			// 生成get
			sb//
					.append("\tpublic ")//
					.append(v)//
					.append(" get")//
					.append(m)//
					.append("(){\n")//
					.append("\t\treturn ")//
					.append(k)//
					.append(";\n")//
					.append("\t}\n\n");//
		});
	}

	public static void main(String[] args) {
		new GenerateEntityMysql(
				"jdbc:mysql://localhost:3306/movie?useUnicode=true&characterEncoding=UTF8", 
				"root", 
				"root", 
				"user",
				"movie",
				"com.movie.entity", 
				"User", 
				"D:\\java\\entity").generate();
	}
}
